package com.linx.park.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.linx.common.core.exception.ServiceException;
import com.linx.common.core.service.PlaceService;
import com.linx.common.core.utils.HttpClientUtils;
import com.linx.common.core.utils.MapstructUtils;
import com.linx.common.core.utils.StringUtils;
import com.linx.common.core.utils.TreeBuildUtils;
import com.linx.common.mybatis.core.page.PageQuery;
import com.linx.common.mybatis.core.page.TableDataInfo;
import com.linx.common.mybatis.helper.ParkHelper;
import com.linx.common.satoken.utils.LoginHelper;
import com.linx.park.domain.ParkInfo;
import com.linx.park.domain.ParkPlace;
import com.linx.park.domain.ParkPlacePoint;
import com.linx.park.domain.bo.ParkPlaceBo;
import com.linx.park.domain.vo.*;
import com.linx.park.mapper.ParkInfoMapper;
import com.linx.park.mapper.ParkPlaceBusinessMapper;
import com.linx.park.mapper.ParkPlaceMapper;
import com.linx.park.mapper.ParkPlacePointMapper;
import com.linx.park.service.IParkPlaceService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 园区区域Service业务层处理
 *
 * @author 泽智科技
 * @date 2024-10-09
 */
@RequiredArgsConstructor
@Service
public class ParkPlaceServiceImpl implements IParkPlaceService, PlaceService {

    private static final Logger log = LoggerFactory.getLogger(ParkPlaceServiceImpl.class);

    private final ParkPlaceMapper parkPlaceMapper;
    @Autowired
    private ParkPlaceBusinessMapper parkPlaceBusinessMapper;

    @Value("${gis.basicMapInformatio.url}")
    private String basicMapInformatioUrl;

    @Value("${gis.basicMapInformatio.workspaceName}")
    private String workspaceName;
    private final ParkInfoMapper parkInfoMapper;

    private final ParkPlacePointMapper pointMapper;

    //@Autowired
    //
    //  private final ParkInfoMapper parkInfoMapper;

    /**
     * 查询园区区域
     *
     * @param parkPlaceId 主键
     * @return 园区区域
     */
    @Override
    public ParkPlaceVo queryById(Long parkPlaceId) {
        return parkPlaceMapper.selectVoById(parkPlaceId);
    }

    /**
     * 分页查询园区区域列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 园区区域分页列表
     */
    @Override
    public TableDataInfo<ParkPlaceVo> queryPageList(ParkPlaceBo bo, PageQuery pageQuery) {
        //Page<ParkPlaceVo> parkPlaceVos = parkPlaceBusinessMapper.selectPlaceBusinessList(bo,pageQuery.build());
        LambdaQueryWrapper<ParkPlace> lqw = buildQueryWrapper(bo);
        Page<ParkPlaceVo> result = parkPlaceMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的园区区域列表
     *
     * @param bo 查询条件
     * @return 园区区域列表
     */
    @Override
    public List<ParkPlaceVo> queryList(ParkPlaceBo bo) {
        LambdaQueryWrapper<ParkPlace> lqw = buildQueryWrapper(bo);
        return parkPlaceMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ParkPlace> buildQueryWrapper(ParkPlaceBo bo) {
        LambdaQueryWrapper<ParkPlace> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getParkInfoId() != null, ParkPlace::getParkInfoId, bo.getParkInfoId());
        lqw.eq(bo.getTenantId() != null, ParkPlace::getTenantId, bo.getTenantId());
        lqw.eq(bo.getPid() != null, ParkPlace::getPid, bo.getPid());
        lqw.like(StringUtils.isNotBlank(bo.getPlaceName()), ParkPlace::getPlaceName, bo.getPlaceName());
        lqw.eq(bo.getType() != null, ParkPlace::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getParkInfoCode()), ParkPlace::getParkInfoCode, bo.getParkInfoCode());
        lqw.eq(ParkPlace::getDelFlag, "0");
        lqw.eq(bo.getParkBuildingId() != null, ParkPlace::getParkBuildingId, bo.getParkBuildingId());
        return lqw;
    }

    /**
     * 新增园区区域
     *
     * @param bo 园区区域
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(ParkPlaceBo bo) {
        ParkPlace add = MapstructUtils.convert(bo, ParkPlace.class);
        validEntityBeforeSave(add);
        add.setDelFlag("0");
        add.setType(Long.valueOf(1));
        //查询园区id
        //TenantVo tenantVo = parkPlaceBusinessMapper.selectTenan(bo.getTenantId());
        //add.setPid(tenantVo.getId());
        add.setPid(bo.getParkInfoId());
        boolean flag = parkPlaceMapper.insert(add) > 0;
        if (flag) {
            bo.setParkPlaceId(add.getParkPlaceId());
        }
        return flag;
    }

    /**
     * 修改园区区域
     *
     * @param bo 园区区域
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(ParkPlaceBo bo) {
        ParkPlace update = MapstructUtils.convert(bo, ParkPlace.class);
        validEntityBeforeSave(update);
        //TenantVo tenantVo = parkPlaceBusinessMapper.selectTenan(bo.getTenantId());
        //update.setPid(tenantVo.getId());
        update.setPid(bo.getParkInfoId());
        return parkPlaceMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ParkPlace entity) {
        //TODO 做一些数据校验,如唯一约束
        //查询园区
        int num = parkPlaceBusinessMapper.selectParkPlaceInfoNumById(entity.getParkInfoId());
        if (0 == num) {
            throw new ServiceException("园区不存在");
        }

        UpdateWrapper<ParkPlace> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("park_building_id", entity.getParkInfoId()) // 设置更新条件，这里是id等于userId
            .set("park_building_name", entity.getPlaceName()); // 设置要更新的字段，这里是email字段更新为newEmail
        parkPlaceMapper.update(updateWrapper); // 执行更新操作
        //entity.setParkInfoCode(sysTenantVo.getParkInfoCode());
    }

    /**
     * 校验并批量删除园区区域信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }

        if (ids.isEmpty()) {
            throw new ServiceException("请选择需要删除的数据");
        }

        List<ParkPlaceVo> parkPlaceVos = parkPlaceMapper.selectVoBatchIds(ids, ParkPlaceVo.class);
        parkPlaceVos.forEach(x -> {
            x.setDelFlag("1");
        });
        List<ParkPlace> parkPlaceList = MapstructUtils.convert(parkPlaceVos, ParkPlace.class);
        //return baseMapper.deleteByIds(ids) > 0;
        UpdateWrapper<ParkPlace> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("park_building_id", ids) // 设置更新条件，这里是id等于userId
            .set("del_flag", "1"); // 设置要更新的字段，这里是email字段更新为newEmail
        parkPlaceMapper.update(updateWrapper); // 执行更新操作


        return parkPlaceMapper.updateBatchById(parkPlaceList);


        //return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public List<Tree<Long>> selectParkTreeList(ParkPlaceBo bo) {

        LambdaQueryWrapper<ParkPlace> lqw = buildQueryWrapper(bo);
        List<ParkPlaceVo> parkPlaceVos = parkPlaceBusinessMapper.selectParkTreeList(lqw);
        return buildDeptTreeSelect(parkPlaceVos);

    }

    @Override
    public List<Tree<Long>> buildDeptTreeSelect(List<ParkPlaceVo> parkPlaceVos) {
        if (CollUtil.isEmpty(parkPlaceVos)) {
            return CollUtil.newArrayList();
        }
        List<Tree<Long>> trees = TreeBuildUtils.buildPark(parkPlaceVos, (dept, tree) -> {
            tree.put("parkBuildingCode", dept.getParkBuildingCode());
            tree.put("parkBuildingAreaCode", dept.getParkBuildingAreaCode());
            tree.put("parkBuildingFloorCode", dept.getParkBuildingFloorCode());
            tree.put("parkBuildingRoomCode", dept.getParkBuildingRoomCode());
            tree.put("parkPlaceCode", dept.getParkPlaceCode());
            tree.put("longitude", dept.getLongitude());
            tree.put("latitude", dept.getLatitude());
            tree.put("grade", dept.getGrade());
            tree.put("path", dept.getPath());
            tree.setId(dept.getParkPlaceId());
            tree.setParentId(dept.getPid());
            tree.setName(dept.getPlaceName());
        });

        return trees;
    }

    @Override
    public List<Tree<Long>> parkTreeList(ParkPlaceBo bo) {
        List<ParkPlaceVo> parkPlaceVoList = new ArrayList<>();
        List<ParkInfoVo> parkInfoVos = new ArrayList<>();
        //List<TenantVo> tenantVos = parkPlaceBusinessMapper.selectTenanList();
        //获取当前选择园区
        String parkInfoId = ParkHelper.getparkInfoId();
        if (StringUtils.isNotEmpty(parkInfoId)) {
            bo.setParkInfoId(Long.valueOf(parkInfoId));
        }


        if (LoginHelper.isSuperAdmin()) {
            parkInfoVos = parkPlaceBusinessMapper.selectParkListByUserId(null, Long.valueOf(parkInfoId));
        } else {
            parkInfoVos = parkPlaceBusinessMapper.selectParkListByUserId(LoginHelper.getUserId(),
                    Long.valueOf(parkInfoId));
        }
        if (parkInfoVos != null && parkInfoVos.size() > 0) {
            parkInfoVos.stream().forEach(x -> {
                ParkPlaceVo parkPlaceVo = new ParkPlaceVo();
                parkPlaceVo.setParkPlaceId(x.getParkInfoId());
                parkPlaceVo.setPid(Long.valueOf(0));
                parkPlaceVo.setPlaceName(x.getParkName());
                parkPlaceVo.setGrade(1);
                parkPlaceVo.setPath(x.getPath());
                parkPlaceVoList.add(parkPlaceVo);
            });
            LambdaQueryWrapper<ParkPlace> lqw = buildQueryWrapper(bo);
            List<ParkPlaceVo> parkPlaceVos = parkPlaceBusinessMapper.selectParkTreeList(lqw);
            parkPlaceVoList.addAll(parkPlaceVos);
        }


        return buildDeptTreeSelect(parkPlaceVoList);
    }


    @Override
    public String getPlaceNameById(String placeId) {
        ParkPlace parkPlace = parkPlaceMapper.selectById(Long.valueOf(placeId));
        if (parkPlace != null) {
            return parkPlace.getPlaceName();
        }
        return "";
    }


    @Override
    public Boolean importData(List<ParkPlaceImportVo> list) {
        //获取楼栋级别数据
        // 筛选name为空的数据
        List<ParkPlaceImportVo> result = list.stream()
            .filter(obj ->
                StringUtils.isNotBlank(obj.getParkBuildingCode())
                    && StringUtils.isEmpty(obj.getParkBuildingAreaCode())) //
            // 判断字段为空
            .collect(Collectors.toList());

        //楼栋
        List<ParkPlace> convert = MapstructUtils.convert(result, ParkPlace.class);
        convert.stream().forEach(x -> {
            if (StringUtils.isEmpty(x.getPlaceName())) {
                x.setPlaceName("暂无");
            }
            x.setType(Long.valueOf(1));
            x.setPid(Long.valueOf(1));
            x.setParkInfoId(Long.valueOf(1));
            x.setParkInfoName("云南建投国际供应链示范中心");
            x.setParkInfoCode("CN65-001-YJWLY");
            x.setParkPlaceCode(x.getParkBuildingCode());
            x.setParkBuildingCode(null);
        });

        parkPlaceMapper.insertBatch(convert);

        //楼栋区域
        List<ParkPlaceImportVo> result1 = list.stream()
            .filter(obj ->
                StringUtils.isNotBlank(obj.getParkBuildingCode()) &&
                    StringUtils.isNotBlank(obj.getParkBuildingAreaCode())
                    && StringUtils.isEmpty(obj.getParkBuildingFloorCode())) // 判断字段为空
            .collect(Collectors.toList());

        //将convert与result1中parkBuildingCode相同的parkPlaceId放到result1中的pid和parkBuildingId中
        List<ParkPlace> convert1 = MapstructUtils.convert(result1, ParkPlace.class);
        convert1.stream().forEach(x -> {
            convert.stream().forEach(y -> {
                if (("CN65-001-YJWLY-" + x.getParkBuildingCode()).equals(y.getRoomCode())) {
                    if (StringUtils.isEmpty(x.getPlaceName())) {
                        x.setPlaceName("暂无");
                    }
                    x.setPid(y.getParkPlaceId());
                    x.setParkBuildingId(y.getParkPlaceId());
                    x.setParkBuildingCode(y.getParkPlaceCode());
                    x.setParkBuildingName(y.getPlaceName());
                    x.setType(Long.valueOf(2));
                    x.setParkInfoId(Long.valueOf(1));
                    x.setParkInfoName("云南建投国际供应链示范中心");
                    x.setParkInfoCode("CN65-001-YJWLY");
                    x.setParkPlaceCode(x.getParkBuildingAreaCode());
                    x.setParkBuildingAreaCode(null);
                }
            });
        });
        parkPlaceMapper.insertBatch(convert1);

        //楼栋区域楼层
        List<ParkPlaceImportVo> result2 = list.stream()
            .filter(obj ->
                StringUtils.isNotBlank(obj.getParkBuildingCode()) &&
                    StringUtils.isNotBlank(obj.getParkBuildingAreaCode()) &&
                    StringUtils.isNotBlank(obj.getParkBuildingFloorCode())
                    && StringUtils.isEmpty(obj.getParkBuildingRoomCode())
            ) // 判断字段为空
            .collect(Collectors.toList());

        //将convert与result1中parkBuildingCode相同的parkPlaceId放到result1中的pid和parkBuildingId中
        List<ParkPlace> convert2 = MapstructUtils.convert(result2, ParkPlace.class);
        convert2.stream().forEach(x -> {
            convert1.stream().forEach(y -> {
                if (("CN65-001-YJWLY-" + x.getParkBuildingCode() + "-" + x.getParkBuildingAreaCode()).equals(y.getRoomCode())) {
                    if (StringUtils.isEmpty(x.getPlaceName())) {
                        x.setPlaceName("暂无");
                    }
                    x.setPid(y.getParkPlaceId());
                    x.setType(Long.valueOf(3));
                    x.setParkInfoId(Long.valueOf(1));
                    x.setParkInfoName("云南建投国际供应链示范中心");
                    x.setParkInfoCode("CN65-001-YJWLY");

                    x.setParkBuildingId(y.getParkBuildingId());
                    x.setParkBuildingCode(y.getParkBuildingCode());
                    x.setParkBuildingName(y.getParkBuildingName());

                    x.setParkBuildingAreaCode(y.getParkPlaceCode());
                    x.setParkBuildingAreaName(y.getPlaceName());
                    x.setParkBuildingAreaId(y.getParkPlaceId());
                    x.setParkPlaceCode(x.getParkBuildingFloorCode());
                    x.setParkBuildingFloorCode(null);


                }
            });
        });
        parkPlaceMapper.insertBatch(convert2);


        //楼栋房间
        List<ParkPlaceImportVo> result3 = list.stream()
            .filter(obj ->
                StringUtils.isNotBlank(obj.getParkBuildingCode()) &&
                    StringUtils.isNotBlank(obj.getParkBuildingAreaCode()) &&
                    StringUtils.isNotBlank(obj.getParkBuildingFloorCode()) &&
                    StringUtils.isNotBlank(obj.getParkBuildingRoomCode())) // 判断字段为空
            .collect(Collectors.toList());

        //将convert与result1中parkBuildingCode相同的parkPlaceId放到result1中的pid和parkBuildingId中
        List<ParkPlace> convert3 = MapstructUtils.convert(result3, ParkPlace.class);
        convert3.stream().forEach(x -> {
            convert2.stream().forEach(y -> {
                if (("CN65-001-YJWLY-" + x.getParkBuildingCode() + "-" + x.getParkBuildingAreaCode() + "-" + x.getParkBuildingFloorCode()).equals(y.getRoomCode())) {
                    if (StringUtils.isEmpty(x.getPlaceName())) {
                        x.setPlaceName("暂无");
                    }
                    x.setPid(y.getParkPlaceId());
                    x.setType(Long.valueOf(4));
                    x.setParkInfoId(Long.valueOf(1));
                    x.setParkInfoName("云南建投国际供应链示范中心");
                    x.setParkInfoCode("CN65-001-YJWLY");

                    x.setParkBuildingId(y.getParkBuildingId());
                    x.setParkBuildingCode(y.getParkBuildingCode());
                    x.setParkBuildingName(y.getParkBuildingName());

                    x.setParkBuildingAreaCode(y.getParkBuildingAreaCode());
                    x.setParkBuildingAreaName(y.getParkBuildingAreaName());
                    x.setParkBuildingAreaId(y.getParkBuildingAreaId());

                    x.setParkBuildingFloorCode(y.getParkPlaceCode());
                    x.setParkBuildingFloorName(y.getPlaceName());
                    x.setParkBuildingFloorId(y.getParkPlaceId());

                    x.setParkPlaceCode(x.getParkBuildingRoomCode());
                    x.setParkBuildingRoomCode(null);


                }
            });
        });
        parkPlaceMapper.insertBatch(convert3);


        System.out.println("fuzhi");

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean syncDate() {
        Map map = new HashMap();
        map.put("H-Invoke-Path-workspaceName", workspaceName);

        String s = null;
        try {
            s = HttpClientUtils.sendGet(basicMapInformatioUrl, null, map);
            //将返回的json转换为对象
            List<ParkPlaceMapsPathVo> parkPlaceMapsPathVoList = JSON.parseArray(s, ParkPlaceMapsPathVo.class);
            if (parkPlaceMapsPathVoList == null || parkPlaceMapsPathVoList.size() <= 0) {
                throw new ServiceException("同步数据失败");
            }
            //过滤出parkPlaceMapsPathVoList中name为Black_outdoor_map_cn的数据
            List<ParkPlaceMapsPathVo> parkPlaceMapsPathVoInfoList =
                parkPlaceMapsPathVoList.stream().filter(parkPlaceMapsPathVo -> parkPlaceMapsPathVo.getName().contains("Black_outdoor_map_cn")).collect(Collectors.toList());
            if (parkPlaceMapsPathVoInfoList != null && parkPlaceMapsPathVoInfoList.size() > 0) {
                //根据ParkInfoCode修改parkInf表中path数据
                parkPlaceMapsPathVoInfoList.stream().forEach(x -> {
                    UpdateWrapper<ParkInfo> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("park_info_code", "CN65-001-YJWLY")
                        .set("path", x.getPath());
                    parkInfoMapper.update(updateWrapper);

                });
            }
            //查询出grade为4的数据库数据
            List<ParkPlace> parkPlaceList =
                parkPlaceMapper.selectList(new LambdaQueryWrapper<ParkPlace>().eq(ParkPlace::getGrade, 4));
            if (parkPlaceList != null && parkPlaceList.size() > 0) {
                parkPlaceList.stream().forEach(parkPlace -> {
                    parkPlaceMapsPathVoList.stream().forEach(parkPlaceMapsPathVo -> {
                        if (parkPlace.getGrade() == 4) {
                            if (parkPlace.getParkBuildingCode().equals("SF1")) {
                                String name =
                                    "Black_floor_map_" + parkPlace.getParkPlaceCode() + "_" + parkPlace.getParkBuildingCode() + "_" + parkPlace.getParkBuildingAreaCode() + "_cn";
                                if (name.equals(parkPlaceMapsPathVo.getName())) {
                                    parkPlace.setPath(parkPlaceMapsPathVo.getPath());
                                }
                            } else {
                                String name =
                                    "Black_floor_map_" + parkPlace.getParkPlaceCode() + "_" + parkPlace.getParkBuildingCode() + "_cn";
                                if (name.equals(parkPlaceMapsPathVo.getName())) {
                                    parkPlace.setPath(parkPlaceMapsPathVo.getPath());

                                }
                            }

                        }


                    });
                });
            } else {
                log.error("查询数据库数据为空");
                throw new ServiceException("同步数据失败");
            }

            return parkPlaceMapper.updateBatchById(parkPlaceList);
        } catch (IOException e) {
            log.error("同步GIS瓦片地址路径异常", e.getMessage());
            throw new RuntimeException(e);
        }

    }


    @Override
    public void importPointData(List<ParkPlacePointImportVo> pointImportVos) {
        if (pointImportVos.size() > 0) {
            //清空数据
            pointMapper.delete(null);
            //点位信息批量新增组参
            List<ParkPlacePoint> points = pointImportVos.stream().map(
                item -> {
                    ParkPlacePoint point = MapstructUtils.copy(item, ParkPlacePoint.class);
                    QueryWrapper<ParkPlace> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("room_code", item.getPointCode());
                    ParkPlace place = parkPlaceMapper.selectOne(queryWrapper);
                    point.setParkPlaceId(place.getParkPlaceId());
                    point.setRoomCode(place.getRoomCode());
                    point.setParkInfoId(Long.valueOf(ParkHelper.getparkInfoId()));
                    return point;
                }
            ).collect(Collectors.toList());
            pointMapper.insertBatch(points);
        }
    }

    @Override
    public List<ParkPlacePointVo> selectParkPlacePointByPlaceId(Long parkPlaceId) {
        List<ParkPlacePointVo> list = pointMapper.selectParkPlacePointByPlaceId(parkPlaceId);
        return list;
    }
}
